package com.yzmoney.wechat.service;

import com.yzmoney.common.constant.Constants;
import com.yzmoney.common.constant.PropertyUtils;
import com.yzmoney.common.util.JDKStackTrace;
import com.yzmoney.common.util.JsonUtils;
import com.yzmoney.wechat.model.general.GeneralReturnCode;
import com.yzmoney.wechat.model.token.AccessToken;
import com.yzmoney.wechat.model.token.AccessTokenJson;
import com.yzmoney.wechat.model.token.OauthToken;
import com.yzmoney.common.util.HttpClientUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;

import java.util.Date;

/**
 * 获取access_token
 * 
 * @author DOVE
 */
@Service
public class WechatAccessTokenService {
	private static Logger logger = Logger
			.getLogger(WechatAccessTokenService.class);

	private AccessToken gzhToken = new AccessToken();

	private AccessToken qyhToken = new AccessToken();

	private static String corpid = PropertyUtils.getValue("corpid", "",
			Constants.QYH_PATH);

	private static String corpsecret = PropertyUtils.getValue("corpsecret", "",
			Constants.QYH_PATH);

	private static String qyhBaseAccess_Token_Url = PropertyUtils.getValue(
			"ACCESS_TOKEN_URL", "", Constants.QYH_PATH);

	private static String grantType = PropertyUtils.getValue("GRANT_TYPE", "",
			Constants.GZH_PATH);

	private static String appid = PropertyUtils.getValue("APPID", "",
			Constants.GZH_PATH);

	private static String appsecret = PropertyUtils.getValue("APPSECRET", "",
			Constants.GZH_PATH);

	private static String gzhBaseAccess_Token_Url = PropertyUtils.getValue(
			"ACCESS_TOKEN_URL", "", Constants.GZH_PATH);

	private static String gzhBaseOAuthUrl = PropertyUtils.getValue("oAuthUrl",
			"", Constants.GZH_PATH);

	/**
	 * 获取access_token
	 * 
	 * @return
	 */
	public String getGZHAccessToken() {
		logger.info(Constants.LOGPRIFIX + "获取 access_token begin");
		Date now = new Date();
		Date last = gzhToken.getLastGetTime();
		if (gzhToken.getAccessToken() == null
				|| (((now.getTime() - last.getTime()) / 1000) > 7000)) {
			httpGetAccessToken(getGZHAccessTokenUrl(), gzhToken);
		}
		logger.info(Constants.LOGPRIFIX + "获取 access_token end");
		return gzhToken.getAccessToken();
	}

	public String refreshGZHAccessToken(){
		logger.info(Constants.LOGPRIFIX + "refresh access_token begin");
		httpGetAccessToken(getGZHAccessTokenUrl(), gzhToken);
		logger.info(Constants.LOGPRIFIX + "refresh access_token end");
		return gzhToken.getAccessToken();
	}

	public String getQYHAccessToken() {
		logger.info(Constants.LOGPRIFIX + "获取 access_token begin");
		Date now = new Date();
		Date last = qyhToken.getLastGetTime();
		if (qyhToken.getAccessToken() == null
				|| (((now.getTime() - last.getTime()) / 1000) > 7000)) {
			httpGetAccessToken(getQYHAccessTokenUrl(), qyhToken);
		}
		logger.info(Constants.LOGPRIFIX + "获取 access_token end");
		return qyhToken.getAccessToken();
	}
	public String refreshQYHAccessToken(){
		logger.info(Constants.LOGPRIFIX + "refresh access_token begin");
		httpGetAccessToken(getQYHAccessTokenUrl(), qyhToken);
		logger.info(Constants.LOGPRIFIX + "refresh access_token end");
		return qyhToken.getAccessToken();
	}

	/**
	 * http 请求获取access_token
	 */
	public boolean httpGetAccessToken(String url, AccessToken token) {
		try {
			logger.info(Constants.LOGPRIFIX + "请求 accessToken begin url:" + url);
			String replyJsonStr = HttpClientUtils.getString(url);
			AccessTokenJson accessTokenJson = JsonUtils.toObject(replyJsonStr,
					AccessTokenJson.class);
			if (accessTokenJson == null) {
				GeneralReturnCode errCode = JsonUtils.toObject(replyJsonStr,
						GeneralReturnCode.class);
				logger.info(Constants.LOGPRIFIX + "请求 accessToken[失败]--"
						+ errCode.toString() + " end url:" + url);
				return false;
			} else {
				token.setAccessToken(accessTokenJson.getAccess_token());
				token.setLastGetTime(new Date());
				logger.info(Constants.LOGPRIFIX + "请求 accessToken[成功] "
						+ token.toString() + " end url:" + url);
				return true;
			}
		} catch (Exception e) {
			logger.warn(Constants.LOGPRIFIX + "请求 accessToken[失败] end url:"
					+ url + JDKStackTrace.getJDKStrack(e));
			return false;
		}
	}

	/**
	 * 网页授权 获取token(内含openId)
	 * 
	 * @return OauthToken[成功] null[失败]
	 */
	public OauthToken getOauthToken(String code) {
		logger.info(Constants.LOGPRIFIX + "请求 OauthToken begin");
		try {
			String url = getGZHOauthUrl(code);
			String replyJsonStr = HttpClientUtils.getString(url);
			OauthToken oauthToken = JsonUtils.toObject(replyJsonStr,
					OauthToken.class);
			if (oauthToken == null) {
				GeneralReturnCode errCode = JsonUtils.toObject(replyJsonStr,
						GeneralReturnCode.class);
				logger.info(Constants.LOGPRIFIX + "请求 OauthToken[失败]--"
						+ errCode.toString() + " end");
				return null;
			} else {
				logger.info(Constants.LOGPRIFIX + "请求 OauthToken[成功] "
						+ oauthToken.toString() + " end");
				return oauthToken;
			}
		} catch (Exception e) {
			logger.info(Constants.LOGPRIFIX + "请求 accessToken[失败]  end"
					+ JDKStackTrace.getJDKStrack(e));
			return null;
		}
	}

	/**
	 * 拼接企业号获取 accessToken的地址
	 * 
	 * @return
	 */
	private static String getQYHAccessTokenUrl() {

		String access_token_url = qyhBaseAccess_Token_Url + "?corpid=" + corpid
				+ "&corpsecret=" + corpsecret;
		return access_token_url;
	}

	/**
	 * 拼接公众号号获取 accessToken的地址
	 * 
	 * @return
	 */
	private static String getGZHAccessTokenUrl() {
		String access_token_url = gzhBaseAccess_Token_Url + "?grant_type="
				+ grantType + "&appid=" + appid + "&secret=" + appsecret;
		return access_token_url;
	}

	/**
	 * 拼接公众号 OAuth2.0请求地址
	 * 
	 * @return
	 */
	private static String getGZHOauthUrl(String code) {
		String oAuthUrl = gzhBaseOAuthUrl + "?appId=" + appid + "&secret="
				+ appsecret + "&code=" + code
				+ "&grant_type=authorization_code";
		return oAuthUrl;
	}

}
